/** @file nim_cpp_sysmsg.h
 * @brief 系统（自定义）消息
 * @copyright (c) 2015-2017, NetEase Inc. All rights reserved
 * @date 2015/2/1
 */

#ifndef _NIM_SDK_CPP_SYSMSG_H_
#define _NIM_SDK_CPP_SYSMSG_H_

#include <functional>
#include <list>
#include <string>
#include "nim_cpp_wrapper/helper/nim_msg_helper.h"
#include "nim_cpp_wrapper/helper/nim_sysmsg_helper.h"
#include "nim_cpp_wrapper/nim_sdk_cpp_wrapper.h"

/**
 * @namespace nim
 * @brief namespace nim
 */
namespace nim {

/** @class SystemMsg
 * @brief 系统消息接口；主要包括查询系统消息、删除系统消息等功能
 */
class NIM_SDK_CPPWRAPPER_DLL_API SystemMsg {
public:
    /// 收到自定义通知回执回调模板
    typedef std::function<void(const SysMessage&)> ReceiveSysmsgCallback;
    /// 发送自定义通知回调模板
    typedef std::function<void(const SendMessageArc&)> SendCustomSysmsgCallback;
    /// 查询系统消息自定义通知回调模板
    typedef std::function<void(int, int, const std::list<SysMessage>&)> QueryMsgCallback;
    /// 修改系统消息自定义通知回调模板
    typedef std::function<void(NIMResCode res_code, int unread_count)> NotifySysmsgResCallback;
    /// 查询系统消息自定义通知未读数回调模板
    typedef NotifySysmsgResCallback QuerySysmsgUnreadCallback;
    /// 设置系统消息自定义通知已读状态回调模板
    typedef NotifySysmsgResCallback ReadAllCallback;
    /// 删除全部系统消息自定义通知回调模板
    typedef NotifySysmsgResCallback DeleteAllCallback;
    /// 批量调整系统消息自定义通知回调模板
    typedef NotifySysmsgResCallback BatchSetCallback;
    /// 修改（单条）系统消息自定义通知回调模板
    typedef std::function<void(NIMResCode, int64_t, int)> NotifySingleSysmsgCallback;
    /// 设置系统消息自定义通知状态回调模板
    typedef NotifySingleSysmsgCallback SetStatusCallback;
    /// 删除系统消息自定义通知回调模板
    typedef NotifySingleSysmsgCallback DeleteCallback;

    /** @fn static void RegSysmsgCb(const ReceiveSysmsgCallback& cb, const std::string& json_extension = "")
     * (全局回调)注册接收系统通知回调接口
     * @param[in] json_extension json扩展参数（备用，目前不需要）
     * @param[in] cb            操作结果的回调函数
     * @return void 无返回值
     * @note 错误码    200:成功
     */
    static void RegSysmsgCb(const ReceiveSysmsgCallback& cb, const std::string& json_extension = "");

    /** @fn static void RegSendCustomSysmsgCb(const SendCustomSysmsgCallback& cb, const std::string& json_extension = "")
     * (全局回调)注册发送透传消息回调函数 （必须全局注册，统一接受回调后分发消息到具体的会话。注意：客户端发包之后，服务器不一定会返回！！！）
     * @param[in] json_extension json扩展参数（备用，目前不需要）
     * @param[in] cb        发送透传消息的回调函数
     * @return void 无返回值
     * @note 错误码    200:成功
     */
    static void RegSendCustomSysmsgCb(const SendCustomSysmsgCallback& cb, const std::string& json_extension = "");

    /** @fn static void SendCustomNotificationMsg(const std::string& json_msg)
     * 发送自定义通知消息
     * @param[in] json_msg        消息体Json, 可以通过CreateCustomNotificationMsg方法自动创建
     * @return void 无返回值
     */
    static void SendCustomNotificationMsg(const std::string& json_msg);

    /** @fn static void SendCustomNotificationMsg(const SysMessage& sys_msg)
     * 发送自定义通知消息
     * @param[in] sys_msg        消息体
     * @return void 无返回值
     */
    static void SendCustomNotificationMsg(const SysMessage& sys_msg);

    /** @fn static std::string CreateCustomNotificationMsg(const std::string& receiver_id,
                                                           const NIMSysMsgType type,
                                                           const std::string& client_msg_id,
                                                           const std::string& content,
                                                           const SysMessageSetting& msg_setting,
                                                           int64_t timetag = 0)
     * 生成自定义通知消息
     * @param[in] receiver_id    接收者id
     * @param[in] type   通知类型
     * @param[in] client_msg_id  本地消息id
     * @param[in] content 通知内容
     * @param[in] msg_setting 通知属性
     * @param[in] timetag 消息时间
     * @return std::string 生成自定义通知消息Json字符串
     */
    static std::string CreateCustomNotificationMsg(const std::string& receiver_id,
        const NIMSysMsgType type,
        const std::string& client_msg_id,
        const std::string& content,
        const SysMessageSetting& msg_setting,
        int64_t timetag = 0);

    /** @fn static bool QueryMsgAsync(int limit_count, int64_t last_time, const QueryMsgCallback& cb, const std::string& json_extension = "")
     * 查询本地系统消息
     * @param[in] limit_count    一次查询数量，建议20
     * @param[in] last_time    上次查询最后一条消息的时间戳
     * @param[in] json_extension json扩展参数（备用，目前不需要）
     * @param[in] cb            查询本地系统消息的回调函数
     * @return bool 检查参数如果不符合要求则返回失败
     */
    static bool QueryMsgAsync(int limit_count, int64_t last_time, const QueryMsgCallback& cb, const std::string& json_extension = "");

    /** @fn static void QueryUnreadCount(const QuerySysmsgUnreadCallback& cb, const std::string& json_extension = "")
     * 查询未读消息数
     * @param[in] json_extension json扩展参数（备用，目前不需要）
     * @param[in] cb            查询未读消息数的回调函数
     * @return void 无返回值
     * @note 错误码    200:成功
     */
    static void QueryUnreadCount(const QuerySysmsgUnreadCallback& cb, const std::string& json_extension = "");

    /** @fn static bool SetStatusAsync(int64_t msg_id,
                                       nim::NIMSysMsgStatus status,
                                       const SetStatusCallback& cb,
                                       const std::string& json_extension = "")
     * 设置消息状态
     * @param[in] msg_id        消息id
     * @param[in] status        消息状态
     * @param[in] json_extension json扩展参数（备用，目前不需要）
     * @param[in] cb            设置消息状态的回调函数
     * @return void 无返回值
     * @note 错误码    200:成功
     *                0:失败
     */
    static bool SetStatusAsync(int64_t msg_id, nim::NIMSysMsgStatus status, const SetStatusCallback& cb, const std::string& json_extension = "");

    /** @fn static void ReadAllAsync(const ReadAllCallback& cb, const std::string& json_extension = "")
     * 设置全部消息为已读
     * @param[in] json_extension json扩展参数（备用，目前不需要）
     * @param[in] cb            设置全部消息为已读的回调函数
     * @return void 无返回值
     * @note 错误码    200:成功
     *                0:失败
     */
    static void ReadAllAsync(const ReadAllCallback& cb, const std::string& json_extension = "");

    /** @fn static bool DeleteAsync(int64_t msg_id, const DeleteCallback& cb, const std::string& json_extension = "")
     * 删除消息
     * @param[in] msg_id        消息id
     * @param[in] json_extension json扩展参数（备用，目前不需要）
     * @param[in] cb            删除消息的回调函数
     * @return bool 检查参数如果不符合要求则返回失败
     * @note 错误码    200:成功
     *                0:失败
     */
    static bool DeleteAsync(int64_t msg_id, const DeleteCallback& cb, const std::string& json_extension = "");

    /** @fn static void DeleteAllAsync(const DeleteAllCallback& cb, const std::string& json_extension = "")
     * 全部删除
     * @param[in] json_extension json扩展参数（备用，目前不需要）
     * @param[in] cb            删除消息的回调函数
     * @return void 无返回值
     * @note 错误码    200:成功
     *                0:失败
     */
    static void DeleteAllAsync(const DeleteAllCallback& cb, const std::string& json_extension = "");

    /** @fn static void SetStatusByTypeAsync(NIMSysMsgType type,
                                             NIMSysMsgStatus status,
                                             const BatchSetCallback& cb,
                                             const std::string& json_extension = "")
     * 按类型设置系统通知状态
     * @param[in] type 类型
     * @param[in] status 状态
     * @param[in] json_extension json扩展参数（备用，目前不需要）
     * @param[in] cb            回调函数
     * @return void 无返回值
     * @note 错误码    200:成功
     *                0:失败
     */
    static void SetStatusByTypeAsync(NIMSysMsgType type, NIMSysMsgStatus status, const BatchSetCallback& cb, const std::string& json_extension = "");

    /** @fn static void DeleteByTypeAsync(NIMSysMsgType type, const BatchSetCallback& cb, const std::string& json_extension = "")
     * 按类型删除系统通知
     * @param[in] type 类型
     * @param[in] json_extension json扩展参数（备用，目前不需要）
     * @param[in] cb            回调函数
     * @return void 无返回值
     * @note 错误码    200:成功
     *                0:失败
     */
    static void DeleteByTypeAsync(NIMSysMsgType type, const BatchSetCallback& cb, const std::string& json_extension = "");

    /** @fn void UnregSysmsgCb()
     * 反注册SysMsg提供的所有回调
     * @return void 无返回值
     */
    static void UnregSysmsgCb();
};

}  // namespace nim

#endif  //_NIM_SDK_CPP_SYSMSG_H_
